
package com.jf.cloud.seckill.manager;

import cn.hutool.core.util.IdUtil;
import com.jf.cloud.common.cache.util.CacheManagerUtil;
import com.jf.cloud.common.cache.util.RedisUtil;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.seckill.service.SeckillSkuService;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;


/**
 * @author zz
 */
@Service
public class SeckillCacheManager {

    /**
     * 秒杀限流前缀
     */
    private final static String SECKILL_LIMIT_PREFIX = "SECKILL_LIMIT_";

    /**
     * 秒杀路径前缀
     */
    private final static String SECKILL_PATH_PREFIX = "SECKILL_PATH_";

    private static final String REDISSON_LOCK_PREFIX = "redisson_lock:";

    private final static String SECKILL_SKU_STOCKS_PREFIX = "SECKILL_SKU_STOCKS_";

    @Autowired
    private SeckillSkuService seckillSkuService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private CacheManagerUtil cacheManagerUtil;

    public String createOrderPath(Long userId) {

        String limitKey = SECKILL_LIMIT_PREFIX + userId;
        int maxCount = 5;

        // 秒杀次数+1
        long seckillNum = RedisUtil.incr(limitKey, 1);

        // 5秒只能提交5次请求
        if (seckillNum == 1) {
            // 5秒后失效
            RedisUtil.expire(limitKey, 5);
        }
        if (seckillNum >= maxCount) {
            // 请求过频繁，请稍后再试
            throw new LuckException("请求过频繁，请稍后再试");
        }
        String orderPath = IdUtil.simpleUUID();

        // 保存秒杀路径，5分钟这个路径就失效
        RedisUtil.set(getPathKey(userId), orderPath, 300);

        return orderPath;
    }

    public void checkOrderPath(Long userId, String orderPath) {
        String cacheOrderPath = RedisUtil.get(getPathKey(userId));

        if (!Objects.equals(cacheOrderPath,orderPath)) {
            // 订单已过期，请重新选择商品进行秒杀
            throw new LuckException("订单已过期，请重新选择商品进行秒杀");
        }
    }

    private String getPathKey(Long userId) {
        return SECKILL_PATH_PREFIX + userId;
    }

}
